package com.simblog.controller;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.simblog.common.constants.Constants;
import com.simblog.common.utils.BeanUtils;
import com.simblog.common.utils.Md5Utils;
import com.simblog.oaknt.domain.User;
import com.simblog.oaknt.domain.VerificationRecord;
import com.simblog.oaknt.service.IEmailService;
import com.simblog.oaknt.service.IUserService;
import com.simblog.oaknt.service.IVerificationRecordService;

@Controller
public class UserController extends BaseController{
	
	private static final Logger logger = LoggerFactory.getLogger(UserController.class);
	
	@Reference
	public IUserService userService;
	@Reference
	private IEmailService emailService;
	@Reference
	private IVerificationRecordService verificationRecordService;
	
	
	
	@RequestMapping("p/user/login")
	public String login(String destination,HttpServletRequest request){
		logger.info("跳转到用户登录页面");
		return "user/login";
	}
	
	
	@ResponseBody
	@RequestMapping(value="p/user/check",method=RequestMethod.POST)
	public JSONObject check(String account,String password,HttpServletRequest request){
		logger.info("用户登录认证");
		
		try{	
			if(Strings.isNullOrEmpty(account)){
				return assemblyJson(null, Constants.ACCOUNT_ERROR, "账号不能为空");
			}
			if(Strings.isNullOrEmpty(password)){
				return assemblyJson(null, Constants.ACCOUNT_ERROR, "密码不能为空");
			}
			
			List<User> list = userService.check(account, Md5Utils.MD5(password));
			
			if(list.size() == 1){
				request.getSession().setAttribute(Constants.LOGIN_USER, list.get(0));
				return assemblyJson(list.get(0).getUserName(), Constants.CHECK_PASS, "登录成功");
			}else{
				return assemblyJson(null, Constants.CHECK_FAIL, "账号或密码错误");
			}
		}catch (Exception e) {
			logger.error("用户登录认证异常" + e.getMessage());
			e.printStackTrace();
			return assemblyJson(null, Constants.RESP_EXCEPTION, "系统异常");
		}
	}
	
	
	@RequestMapping("p/user/reg")
	public String register(){
		logger.info("跳转到用户注册页面");
		return "user/register";
	}
	
	@ResponseBody
	@RequestMapping(value="p/user/unique",method=RequestMethod.POST)
	public JSONObject unique(HttpServletRequest request,String name,String value){
		logger.info("验证{}={}是否唯一",new Object[]{name,value});
		boolean unique = false;
		try{	
			if(!Strings.isNullOrEmpty(name) && !Strings.isNullOrEmpty(value)){
				unique = userService.unique(name, value);
				if(unique)
					return assemblyJson(null, Constants.CHECK_PASS, "可以使用");
				else
					return assemblyJson(null, Constants.CHECK_FAIL, "已存在");
			}else{
				return assemblyJson(null, Constants.CHECK_FAIL, "错误请求,请求参数不完整");
			}
			
		}catch (Exception e) {
			logger.error("注册信息检测异常" + e.getMessage());
			e.printStackTrace();
			return assemblyJson(null, Constants.RESP_EXCEPTION, "系统异常");
		}
	}
	
	@ResponseBody
	@RequestMapping(value="p/user/register", method=RequestMethod.POST)
	public JSONObject register(HttpServletRequest request){
		
		/*初始化User对象*/
		User user = new User();
		try{
			logger.info("初始化User对象");
			Map<String, String> req = new HashMap<>();
			Enumeration<String> em = request.getParameterNames();
			while(em.hasMoreElements()){
				String key = em.nextElement();
				req.put(key, request.getParameter(key));
			}
			//TODO birthday 时间格式转换
			user = BeanUtils.toBean(User.class, req);
		}catch(Exception e){
			logger.error("初始化User对象出错.");
			return assemblyJson(null, Constants.CHECK_FAIL, "错误请求,请求参数异常");
		}
		
		//判断是否允许发送验证邮件
		if(!verificationRecordService.isAllowVerOfRegist(user.getEmail()))
			return assemblyJson(null, Constants.CHECK_FAIL, "请求过于频繁或者次数已达当日上限");
		
		try {
			/*用户的账号、密码、昵称、用户空间、邮箱不能为空*/
			if(Strings.isNullOrEmpty(user.getEmail()) || Strings.isNullOrEmpty(user.getNickName())
				 || Strings.isNullOrEmpty(user.getPassword()) || Strings.isNullOrEmpty(user.getUserName()))
				return assemblyJson(null, Constants.RESP_FAIL, "信息不完整");
			
			//邮箱作为登陆账号
			user.setAccount(user.getEmail());
			
			/*验证关键字段是否已存在*/
			String userName = user.getUserName();
			String account = user.getAccount();
			String nickName = user.getNickName();
			if(	!userService.unique("userName", userName) ||
					!userService.unique("account", account) ||
					!userService.unique("nickName", nickName) ){
				logger.error("非法请求,数据已经被占用.");
				return assemblyJson(null, Constants.RESP_FAIL, "信息被占用");
			}
			
			user.setPassword(Md5Utils.MD5(user.getPassword()));
			user.setIsLock("0");
			user.setIsDelete("0");
			user.setIsVerify("0");
			userService.insert(user);
			
			//TODO 不能直接获取userId
			user = userService.findUserByEmail(user.getEmail());
			
			String uuid = verificationRecordService.addRegisterRecord(user);
			String link = Constants.HOST_DOMAIN + Constants.VERIFICATION_REGISTER_PREFIX + uuid + Constants.REQUEST_TYPE;
			emailService.sendHtmlEmail(Constants.EMAIL_TITLE_REGISTER, link, user.getEmail());
				
			return assemblyJson(null, Constants.RESP_SUCCESS, "注册成功");
			
		} catch (Exception e) {
			return assemblyJson(null, Constants.RESP_FAIL, "注册失败");
		}
	}
	
	@RequestMapping(value="p/user/register/verificate/{uuid}")
	public String verificateRegister(@PathVariable(value="uuid")String uuid){
		
		logger.info("注册验证：{}",uuid);
		
		VerificationRecord record = verificationRecordService.findRecordByUuid(uuid);
		if(record == null)
			return "404";
		
		if(verificationRecordService.verificateRegister(record))
			return "user/login";
		else
			return "user/register";
	}

	
	@RequestMapping("p/user/forget_password")
	public String forgetPassword(){
		logger.info("跳转到忘记密码页面");
		return "user/forget_password";
	}
	
	/**
	 * 密码重置时候发送邮件
	 */
	@ResponseBody
	@RequestMapping("p/user/reset_password_email")
	public JSONObject resetPasswordEmail(String email){
		logger.info("请求给email={}的用户发送重置密码邮件",email);
		Map<String, Object> params = new HashMap<String,Object>();
		try{
			User user = userService.findUserByEmail(email);
			if(user == null){
				return assemblyJson(null, Constants.RESP_FAIL, "用户邮箱有误");
			}
			
			//检查是否允许发送验证邮件
			if(!verificationRecordService.isAllowVerOfPasswd(email))
				return assemblyJson(null, Constants.RESP_SUCCESS, "请求过于频繁或者次数已达当日上限");
			
			//发送邮件
			String uuid = verificationRecordService.addPasswordRecord(user);
			String link = Constants.HOST_DOMAIN + Constants.VERIFICATION_PASSWORD_PREFIX + uuid + Constants.REQUEST_TYPE;
			emailService.sendHtmlEmail(Constants.EMAIL_TITLE_PASSWORD, link, user.getEmail());
			
			return assemblyJson(null, Constants.RESP_SUCCESS, "邮件已经发送到用户邮箱，请查收");
		}catch (Exception e) {
			logger.error("发送重置密码邮件异常");
			e.printStackTrace();
			return systemException();
		}
	}
	
	@RequestMapping("p/user/password/verificate/{uuid}")
	public String verificatePassword(@PathVariable("uuid")String uuid,Model model){
		logger.info("验证忘记密码的uuid={}是否合法",uuid);
		Map<String, Object> params = new HashMap<String,Object>();
		try{
			VerificationRecord record = verificationRecordService.findRecordByUuid(uuid);
			
			if(record == null || record.getIsDelete().equals("1") || record.getIsInvalid().equals("1") || record.getIsVerificate().equals("1")){
				return "404";
			}
			model.addAttribute("uuid", uuid);
			return "user/reset_password";
		}catch (Exception e) {
			logger.error("验证忘记密码的uuid异常");
			e.printStackTrace();
			return "500";
		}
	}
	
	@ResponseBody
	@RequestMapping("p/user/password/reset")
	public JSONObject verificatePassword(String uuid, String password, Model model){
		logger.info("重置密码：uuid={}",uuid);
		Map<String, Object> params = new HashMap<String,Object>();
		try{
			
			if(StringUtils.isBlank(uuid) || StringUtils.isBlank(password))
				return assemblyJson(null, Constants.CHECK_FAIL, "错误请求,请求参数异常");
			
			VerificationRecord record = verificationRecordService.findRecordByUuid(uuid);
			if(record == null)
				return assemblyJson(null, Constants.CHECK_FAIL, "错误请求,请求参数异常");
			
			if(!verificationRecordService.verificatePassword(record)){
				return assemblyJson(null, Constants.CHECK_FAIL, "重置密码失败，请重新尝试");
			}else{
				User user = userService.selectByPrimaryKey(record.getUserId());
				user.setPassword(Md5Utils.MD5(password));
				userService.updateByPrimaryKey(user);
				return assemblyJson(null, Constants.CHECK_PASS, "重置密码成功，请登录");
			}
			
		}catch (Exception e) {
			logger.error("重置密码异常");
			e.printStackTrace();
			return assemblyJson(null, Constants.CHECK_FAIL, "系统异常");
		}
	}
	
	@RequestMapping("v/user/manage_center")
	public String manageCenter(){
		logger.info("跳转到博客管理中心");
		return "user/manage_center";
	}
	
}
